/** ***********************************************************************
*  $Id: $
*
*  COPYRIGHT @2008 CSS CORP PVT LTD
*          
*  This program is free software; you can redistribute it and/or modify it under the terms of 
*  version 2 of the GNU General Public License as published by the Free Software 
*  Foundation.
*
*  The above copyright notice and this permission notice shall be included in all copies 
*  or substantial portions of the Software.
*
*  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 
*  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 
*  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
*  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 
*  HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY
*  WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 
*  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
*  DEALINGS IN THE SOFTWARE.
*
************************************************************************* */

package com.css.ctg.tulip.broker;

import java.util.List;
import java.util.Map;

import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.core.io.FileSystemResource;

import com.css.ctg.tulip.exception.TulipException;
import com.css.ctg.tulip.info.TulipBrokerInfo;
import com.css.ctg.tulip.info.TulipResultInfo;
import com.css.ctg.tulip.jaxb.config.Rulegroup;
import com.css.ctg.tulip.jaxb.config.TulipConfig;
import com.css.ctg.tulip.jaxb.config.TulipService;
import com.css.ctg.tulip.jaxb.config.TulipServiceList;
import com.css.ctg.tulip.service.TulipAbstractAction;
import com.css.ctg.tulip.util.TulipLogger;

/**
 *
 * <p>	Framework broker object.
 * 
 * <p>	Tulip broker can be instantiated only from the Tulip Factory. 
 *  	This class is the entry point to the Tulip framework. 
 * 
 * @version $Rev:
 * 			$
 * 
 */


public class TulipBroker {
	
	private String className = "TulipBroker";
		
	private TulipConfig tulipConfig=null;	
	private List<TulipService> tulipServices=null;
	private TulipService tulipService=null;

	/**
	 * <p> Overloaded constructor to create instance of the object. 
	 * 
	 * @param tulipConfig
	 */
	public TulipBroker(TulipConfig tulipConfig){			
		this.tulipConfig=tulipConfig;
		
		// Logging action
		TulipLogger.log(className, TulipLogger.info, "Creating instance of TulipBroker by passing TulipConfig Instance for the constructor");
	}
	
	/**
	 * <p> 	The executing method of TulipBroker object. This method performs the 
	 * 		execution of framework core functionality by calling the execute method of the
	 * 		Action class implemented by the user. 
	 * 
	 *  
	 * @param info - TulipBrokerInfo Object
	 * @return String - Result XML
	 * @throws TulipException
	 */
	public String execute(TulipBrokerInfo info) throws TulipException {
		
		// Logging action
		TulipLogger.log(className, TulipLogger.info, "Inside execute(TulipBrokerInfo info) of TulipBroker");
		
		String resultXML = null;
		boolean serviceFound = false;	
		TulipResultInfo resultInfo = null;
		BeanFactory beanFactory = null;

		//To check whether the TulipBrokerInfo has all details.
		if(info.getServiceName()!=null && info.getUrl()!=null && info.getServiceName().length()>0 && info.getUrl().length()>0){

			//To get the TulipService according to specified service name.			
			TulipServiceList tulipServiceList=tulipConfig.getTulipServiceList();
			this.tulipServices=tulipServiceList.getTulipService();
			for(int index=0;index<tulipServices.size();index++){
				tulipService=tulipServices.get(index);
				if(tulipService.getName().equals(info.getServiceName())){	
					serviceFound=true;
					break;
				}
			}
			
			if(serviceFound){
				//create beanFactory with the spring CONFIG XML file.
				//BeanFactory beanFactory=new XmlBeanFactory(new FileSystemResource(tulipConfig.getSpringConfigFilePath().getContent()));
				beanFactory=new XmlBeanFactory(new ClassPathResource(tulipConfig.getSpringConfigFilePath().getContent()));
				
				//Create instance for the UserService.
				TulipAbstractAction action=(TulipAbstractAction)beanFactory.getBean(tulipService.getServiceimpl());

				try {
					//calling execute(mapping,info) of TulipAbstractAction.
					resultInfo=action.execute(tulipService,beanFactory,info);
					
				} catch (TulipException te) {
					throw new TulipException(className, te);
				}

				//calling generateXML() to generate the XML with the result obtained. 
				resultXML=generateXML(resultInfo.getResult(),tulipService);
			}
			else {
				throw new TulipException(className, "Required Service not found in Tulip-config.xml");
			}
		}
		else
			throw new TulipException(className, "Broker info not set correctly");

		//returns the resultInfo to the user in XML format
		return resultXML; 
	}


	/**
	 * For generating XML using the result obtained.
	 * 
	 * @param map - Map<String, String>
	 * @return String - XML
	 * 
	 */	
	protected String generateXML(Map<String, String>  resultMap,TulipService tulipService){	
		// Logging action
		TulipLogger.log(className, TulipLogger.info, "Inside generateXML(Map<String, String>  resultMap,TulipService tulipService) of TulipBroker");
		
		String resultString="<?xml version=\"1.0\" encoding=\"UTF-8\"?><tulip-service-result><tulip-service name=\""+tulipService.getName()+"\">";	
		List<Rulegroup> ruleGroup=tulipService.getRulegroup();

		//Iterating the ruleGroup and appending to resultString.
		for(int i=0;i<ruleGroup.size();i++){	
			String ruleGroupName=ruleGroup.get(i).getName();
			String groupWeightage=ruleGroup.get(i).getWeightage();
			resultString+="<rulegroup name=\""+ruleGroupName+"\" weightage=\""+groupWeightage+"\">";

			//Iterating the rule and appending to resultString.
			for(int j=0;j<ruleGroup.get(i).getRule().size();j++){
				String ruleName=ruleGroup.get(i).getRule().get(j).getName();
				String ruleDesc=ruleGroup.get(i).getRule().get(j).getDesc();			
				String ruleWeightage=ruleGroup.get(i).getRule().get(j).getWeightage();

				//For the rules which pass. 
				if(resultMap.containsKey(ruleName)){				
					resultString+="<rule name=\""+ruleName+"\" desc=\""+ruleDesc+"\" weightage=\""+ruleWeightage+"\">";

				if(resultMap.get(ruleGroup.get(i).getRule().get(j).getName()).equals("true")){
					resultString+="<result status=\"pass\"/>";
				}

				//For the rules which fails.
				else if(resultMap.get(ruleGroup.get(i).getRule().get(j).getName()).equals("false")){ 
					String ruleFailureCaseCause=ruleGroup.get(i).getRule().get(j).getFailurecase().getCause().getContent();
					String ruleFailureCaseSolution=ruleGroup.get(i).getRule().get(j).getFailurecase().getSolution().getContent();
					resultString+="<result status=\"fail\"><cause>"+ruleFailureCaseCause+"</cause><solution>"+ruleFailureCaseSolution+"</solution></result>";
				}
				resultString+="</rule>";
				}				
			}
			resultString+="</rulegroup>";
		}
		resultString+="</tulip-service></tulip-service-result>";
		
		return resultString; 
	}
}


